Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

162
Visualizações
React Components "flickers" on load, since state gets overriden

I work on a todo app with React and things become clearer, but I struggle to undersand the "lifecycle". In VueJS I know a ComponentDidMount() hook, which would help me to solve this issue if I guess, but in React I can´t find it out.

I have an array of todos like this: const todos = [{description: "walk dog", done: false}]

This is the initial state of my app:

const [alltodos, handleTodos] = useState([]);

On load I use this useEffect hook to get data from localStorage.

  useEffect(() => {
    const items = localStorage.getItem("todos");
    const parsed = JSON.parse(items);
    handleTodos(parsed);
  }, []);

I count my todos with this function:

  const countTodos = () => {
    const donetodos = alltodos.filter((item) => {
      return !item.done;
    });

    countOpen(donetodos.length);
  };

I update the count if a dependency changes:

  useEffect(() => {
    countTodos();
    localStorage.setItem("todos", JSON.stringify(alltodos));
  }, [alltodos]);

So what happens is that the counter starts with 0 and than "flickers" for a milisecond before it shows the number of todos which I get from localstorage.

Is there a way to prevent that behaviour? As far as I know the component gets rendered FIRST and then the useEffect hook gets triggered. How I render my component AFTER the data is pulled from localstorage?

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

The best way to do this would be with a lazy initial state. Also, cleaning up the variables and using a standardized [variable, setVariable] will save you headache debugging in the future.

const [alltodos, setAlltodos] = useState(() => {
    const items = localStorage.getItem("todos");
    const parsed = JSON.parse(items);
    return parsed || "";
});
about 4 years ago · Juan Pablo Isaza Relatório

0

Initialize the allTodos state with null. As long as this state is null, render a notification or just return null to render nothing.

You can calculate the open todos count directly from the current alltodos state, without the need of useEffect.

const [alltodos, handleTodos] = useState(null);

useEffect(() => {
  const items = localStorage.getItem("todos");
  const parsed = items ? JSON.parse(items) : [];
  handleTodos(parsed);
}, []);

useEffect(() => {
  localStorage.setItem("todos", JSON.stringify(alltodos));
}, [alltodos]);

if(alltodos === null) return 'Loading todos list';

// this is derived from state, so you don't have to create a state for it
const openTodosCount = alltodos.reduce((acc, o) => acc + !o.done, 0);
about 4 years ago · Juan Pablo Isaza Relatório

0

The fastest way would be to add new state that would be responsible for loading. For example

const [isLoading, setIsLoading] = useState(true);

set it initially on true and then after you do all your calculations change it to false.

Then you can depend on that state and show div with a text "Loading" or anything else but when isLoading would go to false it will show component elements.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda